interface Date {
  AddDay(day: number): Date;

  Minus(d: Date): number;

  Format(fmt: string): string;
}

Date.prototype.AddDay = function (day: number) {
  return new Date(this.getTime() + day * 24 * 60 * 60 * 1000);
};
Date.prototype.Minus = function (d: Date) {
  const result = this.getTime() - d.getTime();
  return result / (24 * 60 * 60 * 1000);
};
Date.prototype.Format = function (fmt: string) {
  var o = {
    'M+': this.getMonth() + 1, //月份
    'd+': this.getDate(), //日
    'h+': this.getHours(), //小时
    'm+': this.getMinutes(), //分
    's+': this.getSeconds(), //秒
    'q+': Math.floor((this.getMonth() + 3) / 3), //季度
    'S': this.getMilliseconds() //毫秒
  };
  if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length));
  for (var k in o)
    if (new RegExp('(' + k + ')').test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)));
  return fmt;
};

interface String {
  Utf8ToUnicode(): Array<number>;

  en(): string;

  de(): string;
}

String.prototype.en = function () {
  let content: string = this;
  return content.Utf8ToUnicode().en().UnicodeToUtf8();
};
String.prototype.de = function () {
  let content: string = this;
  //console.log(content);
  return content.Utf8ToUnicode().de().UnicodeToUtf8();
};
String.prototype.Utf8ToUnicode = function () {
  var i, j;
  var uCode;
  var temp = new Array();
  let unicode = '';

  for (i = 0, j = 0; i < this.length; i++) {
    uCode = this.charCodeAt(i);
    if (uCode < 0x100) {                 //ASCII字符
      temp[j++] = 0x00;
      temp[j++] = uCode;
    } else if (uCode < 0x10000) {
      temp[j++] = (uCode >> 8) & 0xff;
      temp[j++] = uCode & 0xff;
    } else if (uCode < 0x1000000) {
      temp[j++] = (uCode >> 16) & 0xff;
      temp[j++] = (uCode >> 8) & 0xff;
      temp[j++] = uCode & 0xff;
    } else if (uCode < 0x100000000) {
      temp[j++] = (uCode >> 24) & 0xff;
      temp[j++] = (uCode >> 16) & 0xff;
      temp[j++] = (uCode >> 8) & 0xff;
      temp[j++] = uCode & 0xff;
    } else {
      break;
    }
  }
  temp.length = j;
  return temp;
};

interface Array<T> {
  UnicodeToUtf8(): string;

  en(): Array<number>;

  de(): Array<number>;
}

Array.prototype.UnicodeToUtf8 = function () {
  let utf8str = '';
  let uchar;
  let i: number;
  for (i = 0; i < this.length; i += 2) {
    uchar = (this[i] << 8) | this[i + 1];               //UNICODE为2字节编码，一次读入2个字节
    utf8str = utf8str + String.fromCharCode(uchar);    //使用String.fromCharCode强制转换
  }
  return utf8str;
};

Array.prototype.en = function () {
  let i = 0;
  const max = this.length - 2;
  for (i = 0; i < this.length; i += 4) {
    if (max > i) {
      const first = this[i];
      this[i] = this[i + 1];
      this[i + 1] = this[i + 2];
      this[i + 2] = this[i + 3];
      this[i + 3] = first;
    }
    else {
      const first = this[i];
      this[i] = this[i + 1];
      this[i + 1] = first;
    }
  }
  return this;
};

Array.prototype.de = function () {
  let i = 0;
  const max = this.length - 2;
  for (i = 0; i < this.length; i += 4) {
    if (max > i) {
      const last = this[i + 3];
      this[i + 3] = this[i + 2];
      this[i + 2] = this[i + 1];
      this[i + 1] = this[i];
      this[i] = last;
    }
    else {
      const last = this[i + 1];
      this[i + 1] = this[i];
      this[i] = last;
    }
  }
  return this;
};


